#!/usr/bin/perl

package RoundRobin;
use Scheduler;
use Switch;
use strict;
our @ISA = qw(Scheduler);    

# Override constructor
 
sub new {
    my ($class) = @_;

    my $self = $class->SUPER::new( $_[1], $_[2], $_[3]);
	   
	$self->{_quantum} = $_[2];
	$self->{_kernels} = $_[3];
	$self->{_ultAlgorithmin} = $_[4];
	$self->{_ThreadQuantum} = $_[5];
	$self->{_quantumUsed} = 0;
	$self->{_quantumUsed2} = 0;
	$self->{_ProcessAlgorithm} = 'RR';
    
    bless $self, $class;
    return $self;
}

sub doTick{
	my( $self ) = @_;
	
	my $currentProcess;
	
	#1er kERNEL
	if(!$self->{_executing}){
		
		my $proc;
		my $i=0;
		
		if(@{$self->{_ready}}>0){
			
			foreach $proc (@{$self->{_ready}}){
			
			if(@{$proc->getBursts()} || $proc->hasUlts()){
				$currentProcess = $proc;
				last;
			}			
			$i++;
		  }
		}else{
			$self->{_quantumUsed} = 0;
		}
		
		if($currentProcess){
			
			splice @{$self->{_ready}}, $i, 1;
			
			if($currentProcess->hasUlts() && ($self->{_ultAlgorithmin} eq "SPN" || $self->{_ultAlgorithmin} eq "SRT")){
				$currentProcess->orderUltByMinor();
			}elsif($currentProcess->hasUlts() && $self->{_ultAlgorithmin} eq "HRRN"){
				$currentProcess->orderUltByPriorityHRRN($self->{_ticks});
			}
			
			
			$self->{_executing} = $currentProcess;
		}
	}
	
	#2do KERNEL
	if($self->{_kernels} eq 2 && !$self->{_executing2}){
		$currentProcess=undef;
		my $proc;
		my $i=0;
		
		if(@{$self->{_ready}}>0){
			
			foreach $proc (@{$self->{_ready}}){
			
			if(@{$proc->getBursts()} || $proc->hasUlts()){
				$currentProcess = $proc;
				last;
			}			
			
			$i++;
			
		  }
		
		}else{
			$self->{_quantumUsed2} = 0;
		}
		
		if($currentProcess){
			
			splice @{$self->{_ready}}, $i, 1;
			
			if($currentProcess->hasUlts() && ($self->{_ultAlgorithmin} eq "SPN" || $self->{_ultAlgorithmin} eq "SRT")){
				$currentProcess->orderUltByMinor();
			}elsif($currentProcess->hasUlts() && $self->{_ultAlgorithmin} eq "HRRN"){
				$currentProcess->orderUltByPriorityHRRN($self->{_ticks});
			}
			
			
			$self->{_executing2} = $currentProcess;
		}



	}
	
	#Si no hay nada en La cola de Listos no Suma quantum.(En caso de que se ejecute S.O.)
	if($self->{_executing}){ 
		$self->{_quantumUsed} += 1;
	}
	
	if($self->{_kernels} eq 2 && $self->{_executing2}){
		$self->{_quantumUsed2} += 1;
	}
		
}

sub _removeUltnada{
	my($self,$currentProcess, $scheduler) = @_;
	if($currentProcess && $currentProcess->hasUlts()){
		$currentProcess->{_ults} = @{$scheduler->{_ready}};
		$currentProcess->setQuantumLeft($self->{_quantumUsed2});
	}
}

sub _doAfterProcess{
	my( $self ) = @_;
	
	if($self->{_quantumUsed} == $self->{_quantum}){
		my $currentProcess;
		
		if($self->{_executing}){
			$currentProcess = $self->{_executing};
			$self->{_executing}=undef;
						
			push $self->{_auxList},$currentProcess;
		}
		$self->{_quantumUltUsed} = 0;
		$self->{_quantumUsed} = 0;	
	}
	if($self->{_quantumUsed2} == $self->{_quantum}){
		my $currentProcess;
		
		if($self->{_executing2}){
			$currentProcess = $self->{_executing2};
			$self->{_executing2}=undef;
			
			
			push $self->{_auxList},$currentProcess;
		}
		$self->{_quantumUltUsed2} = 0;
		$self->{_quantumUsed2} = 0;	
	}
}

sub _doAfterBloqued{
	my( $self, $kernel ) = @_;
	if(!defined($self->{_executing})){
		$self->{_quantumUsed} = 0;
	}
	if($kernel>1 && (!defined($self->{_executing2}))){
		$self->{_quantumUsed2} = 0;		
	}
}
1;
